#include "CServer.h"

#include "HttpConnection.h"
#include "AsioIOContextPool.h"



// tcp::socket _socket(ioc) 通过构造函数将 _socket 绑定到 ioc
// 意味着该 _socket 的所有异步操作（如 async_read、async_write）均由 ioc 调度。

CServer::CServer(net::io_context& ioc, uint16_t port)
    : _ioc(ioc), _acceptor(ioc, tcp::endpoint(tcp::v4(), port)){
  //std::cout << "Server Start Successfully IP："
  //          << _acceptor.local_endpoint().address()
  //          << " Port: " << _acceptor.local_endpoint().port() << std::endl;
}

CServer::~CServer() {
  std::cout << "CServer::~CServer() " << std::endl;
  if (_acceptor.is_open()) {
    _acceptor.close();
  }
}   

void CServer::Start() {
  //获取当前对象的共享指针self，以确保在异步操作期间CServer对象不会被销毁
  auto self = shared_from_this();

  // 思考为什么使用值捕获，不使用引用捕获？
  // 答：因为在lambda内部
  // 会把_socket转交给HttpConnection管理，所以用的是值捕获。
  auto& io_context = AsioIOContextPool::GetInstance()->getIOContext();
  std::shared_ptr<HttpConnection> new_con =
      std::make_shared<HttpConnection>(io_context);

  _acceptor.async_accept(new_con->GetSocket(),[self, new_con](const beast::error_code& ec) {
    try {
      // 出错就放弃这个连接，继续监听新链接
      if (ec) {
        self->Start();
        return;
      }

      // 处理新链接，创建HttpConnection类管理新链接
      new_con->Start();

      // 继续监听

      self->Start();
      return;

    } catch (const std::exception& e) {
      std::cout << "Error: " << e.what() << std::endl;
      self->Start();
    }
  });
}
